require "trifle/ruby/wrappers/json_transform"

module Trifle
  module Ruby
    class ExceptionPayload

      attr_accessor :env, :exception, :params

      def initialize(env, exception, params = {})
        @env = Trifle::Ruby::JsonTransform.transform(env)
        @exception = exception
        @params = params
      end

      def generate!
        stack = clean_backtrace(exception, "silent")
        full_stack = clean_backtrace(exception, "all")
        begin
          memory = `ps -o rss -p #{Process.pid}`.chomp.split("\n").last.strip.to_i / 1024
          server_memory = memory.to_i
          server_host = Socket.gethostname
          server_ip = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address
        rescue => e
          server_memory = 0
          server_host = "localhost"
          server_ip = "127.0.0.1"
          Logger.error "Unable to get memory, host & IP address information."
        end
        payload = {
          "exception_name" => @exception.class.to_s,
          "exception_message" => @exception.message,
          "stack" => stack,
          "full_stack" => full_stack,
          "full_environment" => @env,
          "environment" => @params["environment"],
          "exception_location" => @params["location"],
          "session" => @params["session"],
          "params" => @params["params"],
          "url" => @params["url"],
          "user_agent" => @params["user_agent"],
          "occurred_at" => DateTime.now,
          "process_id" => Process.pid,
          "memory" => server_memory,
          "host" => server_host,
          "ip" => server_ip,
          "reference_type" => @params["reference_type"],
          "reference_id" => @params["reference_id"]
        }
      end

      def clean_backtrace(exception, level)
        return [] unless exception.backtrace.class == Array
        if defined?(::Rails)
          ::Rails.backtrace_cleaner.clean(exception.backtrace, level.to_sym)
        else
          exception.backtrace
        end
      end

    end
  end
end
